/**
 * 
 */
package org.dragonfire.dasm.directives;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;

import org.dragonfire.dasm.Command;
import org.dragonfire.dasm.CompileException;
import org.dragonfire.dasm.Listing;
import org.dragonfire.dasm.DirectiveManager.Directive;
import org.dragonfire.file.BufferedFile;

/**
 * Includes the contents of a binary file as raw data (similar to a bunch of
 * <code>#{@link org.dragonfire.dasm.directives.Db}</code> statements) into
 * the current compilation. #Includebin accepts any number of files and includes
 * them in the order that they are provided and updates <code>PC</code>'s
 * value accordingly.<br />
 * <br />
 * Format:<br />
 * <code>#INCLUDEBIN <i>&lt;file1&gt;</i>[,<i>&lt;file2&gt;</i>[,...]]</code><br />
 * <br />
 * Parameters:<br />
 * <table>
 * <tr>
 * <td><code>file1</code></td>
 * <td>(String) The name of the file to include</td>
 * </tr>
 * </table><br />
 * Errors:<br />
 * <table>
 * <tr>
 * <td><code>ERROR_STRING_REQUIRED</code></td>
 * <td>Thrown if <code>file1</code> is not a string</td>
 * </tr>
 * <tr>
 * <td><code>ERROR_FILE_OPERATION</code></td>
 * <td>Thrown if <code>file1</code> cannot be read</td>
 * </tr>
 * <tr>
 * <td><code>ERROR_FILE_NOT_FOUND</code></td>
 * <td>Thrown if <code>file1</code> does not exist in the filesystem</td>
 * </tr>
 * </table>
 * 
 * @see org.dragonfire.dasm.directives.Include
 * @author Darth Android
 * @version 2.0
 */
public class Includebin extends Directive {

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ArrayList<Listing> pass1(Command c) {
		ArrayList<Listing> list = new ArrayList<Listing>();
		for (int i = 0; i < c.getParams().length; i++) {
			// get file name
			String file = evalString(c.getParam(i));
			// open a data stream
			DataInputStream dis = new DataInputStream(BufferedFile.openFile(file));
			// attempt to read the file
			try {
				// create buffer
				byte[] data = new byte[dis.available()];
				// read file contents
				dis.read(data);
				// create & add a listing
				Listing l = new Listing(data.length, c);
				l.setMCode(data);
				list.add(l);
			} catch (IOException ioe) {
				// catch file errors
				throw new CompileException("ERROR_FILE_OPERATION", file);
			}
		}
		return list;
	}
}
